package tchk.xyz.lingyuntutorminiprogram.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tchk.xyz.lingyuntutorminiprogram.dto.DashboardStatsDTO;
import tchk.xyz.lingyuntutorminiprogram.dto.OrderAdminDTO;
import tchk.xyz.lingyuntutorminiprogram.entity.Orders;
import tchk.xyz.lingyuntutorminiprogram.entity.SysUser;
import tchk.xyz.lingyuntutorminiprogram.entity.WalletTransaction;
import tchk.xyz.lingyuntutorminiprogram.exception.CustomException;
import tchk.xyz.lingyuntutorminiprogram.mapper.OrdersMapper;
import tchk.xyz.lingyuntutorminiprogram.service.IOrdersService;
import tchk.xyz.lingyuntutorminiprogram.service.IUserService;
import tchk.xyz.lingyuntutorminiprogram.service.IWalletTransactionService;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {
    @Autowired
    private IUserService userService;

    @Autowired
    private IWalletTransactionService walletTransactionService;
    @Override
    public DashboardStatsDTO getDashboardStats() {
        DashboardStatsDTO statsDTO = new DashboardStatsDTO();
        LocalDate today = LocalDate.now();

        // 1. 核心数据统计
        statsDTO.setTodayNewUsers(userService.countTodayNewUsers());
        statsDTO.setTotalUsers(userService.count());
        statsDTO.setTodayCompletedOrders(this.count(new QueryWrapper<Orders>()
                .eq("status", "completed")
                .ge("finish_time", today.atStartOfDay())));

        Object totalGmvObj = this.getMap(new QueryWrapper<Orders>()
                .select("IFNULL(SUM(total_amount), 0) as totalGmv")
                .eq("status", "completed")).get("totalGmv");
        statsDTO.setTotalGmv(new BigDecimal(totalGmvObj.toString()));

        // 2. 近7日订单量趋势
        List<String> last7DaysDate = new ArrayList<>();
        List<Long> last7DaysOrderCount = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        for (int i = 6; i >= 0; i--) {
            LocalDate date = today.minusDays(i);
            last7DaysDate.add(date.format(formatter));
            long count = this.count(new QueryWrapper<Orders>()
                    .ge("create_time", date.atStartOfDay())
                    .lt("create_time", date.plusDays(1).atStartOfDay()));
            last7DaysOrderCount.add(count);
        }
        statsDTO.setLast7DaysDate(last7DaysDate);
        statsDTO.setLast7DaysOrderCount(last7DaysOrderCount);

        // 3. 热门科目分布
        List<Map<String, Object>> popularSubjects = this.listMaps(new QueryWrapper<Orders>()
                .select("subject_name as name", "COUNT(id) as value")
                .groupBy("subject_name")
                .orderByDesc("value")
                .last("LIMIT 5")); // 只查询前5名
        statsDTO.setPopularSubjects(popularSubjects);

        return statsDTO;
    }

    @Override
    public IPage<OrderAdminDTO> getOrderListForAdmin(IPage<OrderAdminDTO> page, String orderNo) {
        return this.baseMapper.findOrderListForAdmin(page, orderNo);
    }

    @Override
    @Transactional
    public void cancelOrderByAdmin(Long orderId, String reason) {
        Orders order = this.getById(orderId);
        if (order == null) {
            throw new CustomException("订单不存在");
        }

        // 只有在非“已完成”或非“已取消”状态下，管理员才能干预
        if ("completed".equals(order.getStatus()) || "cancelled".equals(order.getStatus())) {
            throw new CustomException("订单已终结，无法取消");
        }

        // [核心业务] 如果订单已支付，需要将钱款退还给家长
        if ("pending_confirmation".equals(order.getStatus()) || "in_progress".equals(order.getStatus())) {
            // 找到家长
            SysUser parent = userService.getById(order.getParentId());
            if (parent != null) {
                // 返还金额
                parent.setBalance(parent.getBalance().add(order.getTotalAmount()));
                userService.updateById(parent);

                // 创建一条退款流水
                WalletTransaction transaction = new WalletTransaction();
                transaction.setUserId(parent.getId());
                transaction.setAmount(order.getTotalAmount()); // 正数
                transaction.setBalanceAfter(parent.getBalance());
                transaction.setType("refund");
                transaction.setRelatedId(order.getOrderNo());
                transaction.setDescription("管理员取消订单，退款：" + reason);
                walletTransactionService.save(transaction);
            }
        }

        // 更新订单状态
        order.setStatus("cancelled");
        this.updateById(order);

        // TODO: 发送系统通知给家长和老师，告知订单已被管理员取消
    }
}